﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Noris.Tools.TraceVisualiser.Interface;
using Noris.Tools.TraceVisualiser.Support;
using Noris.Tools.TraceVisualiser.Components;
using Noris.Tools.TraceVisualiser.Forms;
using System.Xml.Linq;

namespace Noris.Tools.TraceVisualiser.TraceData
{
    /// <summary>
    /// Funkce pro spuštění vyhledání událostí podobných, jako je událost pod myší.
    /// </summary>
    internal class Func_Search : Func_Base, IFunctionContextMenuItem
    {
        #region IFunctionContextMenuItem + IPlugin Members
        bool IPlugin.Active { get { return true; } }
        bool IFunctionContextMenuItem.IsFunctionSuitableFor(FunctionContextMenuItemSuitableArgs args)
        {
            args.MenuItems.Add(new FunctionMenuItem(50, "Vyhledej podobné události",
                "Otevře okno Vyhledávání, a naplní do něj informace o vybraném prvku.",
                true, Noris.Tools.TraceVisualiser.Pics.PicLibrary16.Documentpreview_FromFile, null));
            return true;
        }
        bool IFunctionContextMenuItem.IsMenuItemEnabledFor(FunctionContextMenuItemRunArgs args)
        {
            MainAppForm mainAppForm = Steward.MainForm as MainAppForm;
            if (mainAppForm == null) return false;

            EventInfo eventInfo = this.GetEventInfo(args, args.ClickedItem);
            ISearchPatternProvider provider = this._FindSearchProvider(eventInfo);
            return (provider != null);
        }
        void IFunctionContextMenuItem.Run(FunctionContextMenuItemRunArgs args)
        {
            EventInfo eventInfo = this.GetEventInfo(args, args.ClickedItem);
            this._RunSearchPattern(args, eventInfo);
        }
        #endregion
        #region Výkonný kód
        /// <summary>
        /// Metoda vyhledá providera hledání, který implementuje ISearchPatternProvider, 
        /// a který se pro danou událost nejlépe hodí.
        /// </summary>
        /// <param name="eventInfo"></param>
        /// <returns></returns>
        private ISearchPatternProvider _FindSearchProvider(EventInfo eventInfo)
        {
            if (eventInfo == null) return null;             // Kliknout lze i na událost, která není EventInfo (typicky jde o TraceInfo)

            ISearchPatternProvider bestProvider = null;
            float bestPriority = 0f;
            SearchProviderPatternArgs args = new SearchProviderPatternArgs(eventInfo);
            IEnumerable<ISearchProvider> searchers = Steward.GetServiceObjectList<ISearchProvider>(true);
            foreach (ISearchProvider searcher in searchers)
            {
                if (searcher is ISearchPatternProvider)
                {
                    ISearchPatternProvider currProvider = searcher as ISearchPatternProvider;
                    if (currProvider != null)
                    {
                        float currPriority = currProvider.CanSearchByPattern(args);
                        if (currPriority > 0f && (bestPriority <= 0f || currPriority < bestPriority))
                        {
                            bestProvider = currProvider;
                            bestPriority = currPriority;
                        }
                    }
                }
            }
            return bestProvider;
        }
        /// <summary>
        /// Zajistí otevření okna vyhledávání s předvyplněným providerem a parametry podle dodané události
        /// </summary>
        /// <param name="args"></param>
        /// <param name="eventInfo"></param>
        private void _RunSearchPattern(FunctionContextMenuItemRunArgs args, EventInfo eventInfo)
        {
            MainAppForm mainAppForm = Steward.MainForm as MainAppForm;
            if (mainAppForm == null) return;

            ISearchPatternProvider provider = this._FindSearchProvider(eventInfo);
            if (provider == null) return;

            SearchProviderPatternArgs patternArgs = new SearchProviderPatternArgs(eventInfo);
            XElement presetData = provider.CreatePresetData(patternArgs);
            if (presetData != null)
            {
                Type providerType = provider.GetType();
                mainAppForm.SearchOpen(providerType.Namespace + "." + providerType.Name, presetData);
            }
        }
        #endregion
    }
}
